package org.framework.common.api.support.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.framework.common.ext.util.StringUtil;
import org.framework.common.ext.util.file.ExcelUtil;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;

import com.fasterxml.jackson.annotation.JsonAutoDetect;

@JsonAutoDetect
public class ProcedureModel implements Serializable{

	/** serialVersionUID(long):. */
	private static final long serialVersionUID = -3476683659972932930L;

	private String name;
	
	private EChartsModel charts;
	
	private Map<String,Object> params;
	
	/**
	 * 统计图表.
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年9月12日 下午2:08:38
	 */
	public Object charts(final JdbcTemplate jdbc) {
		// 注册存储过程
		registerProcedure(jdbc);
		
		// 设置结果集
		List<String> timelines = charts.getTimeline();
		if(timelines != null && !timelines.isEmpty()){
			for (String timeline : timelines) {
				call.returningResultSet(timeline, new ColumnMapRowMapper());
			}
		}
		
		// 返回图表
		return charts.create(call.execute(getParameterSource()));
	}
	
	/**
	 * 调用存储过程.
	 * @param jdbc
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年9月8日 上午11:11:42
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Object> call(final JdbcTemplate jdbc){
		// 是否有分页
		boolean haslimit = params != null && params.containsKey("_limit");
		
		// 注册存储过程
		registerProcedure(jdbc);
		
		// 增加结果设置
		call.returningResultSet("rows", new ColumnMapRowMapper());
		
		// 增加分页设置
		if(haslimit) call.returningResultSet("total", new ColumnMapRowMapper());
		
		// 调用存储过程
		Map<String, Object> map = call.execute(getParameterSource());
		
		// 创建返回结果
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("rows", map.containsKey("rows") ? map.get("rows") : new ArrayList<>());
		
		// 有分页
		if(haslimit) {
			result.put("total", ((List<Map<String,Object>>)map.get("total")).get(0).get("total"));
		// 无分页
		}else if(map.containsKey("#result-set-2")){
			result.put("#result-set-2", map.get("#result-set-2"));
		}
		return result;
	}
	
	/**
	 * 导出存储过程数据.
	 * @param jdbc
	 * @return
	 * @author chanlong(陈龙)
	 * @param response 
	 * @date 2016年9月8日 上午11:11:42
	 */
	public byte[] export(final HttpServletResponse response){
		return ExcelUtil.export(response, name, String.valueOf(params.get("html")));
	}

	/**
	 * 获取存储过程参数.
	 * @return
	 * @author chanlong(陈龙)
	 * @date 2016年7月22日 下午3:03:49
	 */
	public MapSqlParameterSource getParameterSource() {
		MapSqlParameterSource source = null;
		if (params != null) {
			source = new MapSqlParameterSource();
			Set<Entry<String, Object>> entryset = params.entrySet();
			for (Entry<String, Object> entry : entryset) {
				source.addValue(entry.getKey(), StringUtil.getPramameter(entry.getValue()));
			}
		}
		return source;
	}
	
	private SimpleJdbcCall call;
	
	// 注册存储过程
	private void registerProcedure(final JdbcTemplate jdbc){
		// 创建存储过程
		if(call == null) call = new SimpleJdbcCall(jdbc);
		
		// 注册过程名称
		call.withProcedureName(name);
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public EChartsModel getCharts() {
		return charts;
	}

	public void setCharts(EChartsModel charts) {
		this.charts = charts;
	}

	public Map<String, Object> getParams() {
		return params;
	}

	public void setParams(Map<String, Object> params) {
		this.params = params;
	}
	
	public ProcedureModel addParams(final String key, final Object value){
		if(this.params == null) this.params = new HashMap<String, Object>();
		this.params.put(key, value);
		return this;
	}
	
}
